package com.myPlaneGame;

import com.myPlaneGame.Music.PlayMusic;
import com.myPlaneGame.Utils.GameUtils;
import com.myPlaneGame.obj.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

public class GameCreate extends JFrame implements MouseListener, KeyListener {
    //记录游戏状态的变量
    //0:未开始 1:游戏中 2:暂停 3:失败 4:通关
    public static int state = 0;

    //背景图片对象的属性初始化(背景图从上往下移动)
    Bgobj bgobj;
    //定义一个图片变量(初始化游戏没开始的图片)
    Image offScreenImage;
    //我方飞机的对象
    PlaneObj planeObj;
    //记录游戏图片绘制的次数
    public static int count = 1;
    //敌方1号小boss的对象
    LittleBoss1 littleBoss1;
    //敌方2号小boss的对象
    LittleBoss2 littleBoss2;
    //敌方大boss的对象
    BossObj bossObj;
    //警示标志的对象
    WarningObj warningObj;
    //定义一个变量来记录我方飞机的索引(追踪子弹的定位)
    public static int planeIndex = 0;
    //定义一个变量记录游戏得分
    public static int score = 0;
    public static int MaxScore = 0;
    //定义一个变量控制技能时长
    static int skillCount = 0;
    //创建音乐对象
    PlayMusic musicBg = new PlayMusic();
    PlayMusic musicShoot1 = new PlayMusic();
    PlayMusic musicShoot2 = new PlayMusic();
    PlayMusic musicShoot3 = new PlayMusic();
    PlayMusic musicTracking = new PlayMusic();
    PlayMusic musicWarning = new PlayMusic();

    //页面的显示
    public GameCreate() {
        //设置鼠标点击事件（控制游戏开始）
        this.addMouseListener(this);
        //设置键盘监听事件（控制游戏暂停）
        this.addKeyListener(this);
        //初始化建立一个窗口
        initWindow();
        //初始化数据
        myInitData();
        //这里拿到了我方飞机的索引值(完成追踪导弹)
        planeIndex = GameUtils.gameObjList.indexOf(planeObj);
        //控制游戏运行
        gameWork();
    }

    private void gameWork() {
        //利用循环刷新图片运行过程(游戏图片刷新的主体)
        while (true) {
            //不断创建集合
            createObj();
            //不断刷新创建的页面
            repaint();
            try {
                //背景图片的刷新间隔时间为25ms(防止页面刷新太快)
                Thread.sleep(25);
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }

    private void initWindow() {
        //窗口的大小
        this.setSize(600, 800);
        //窗口的标题
        this.setTitle("飞机大战 v1.0");
        //设置界面置顶（放置界面被其它界面盖住）
        this.setAlwaysOnTop(true);
        //窗口的位置(居中)
        this.setLocationRelativeTo(null);
        //关闭窗口会自动结束进程   (3 == EXIT_ON_CLOSE)
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        //取消图片的默认居中放置
        this.setLayout(null);
        //窗口是否可见
        this.setVisible(true);
    }

    //页面的绘制
    @Override
    public void paint(Graphics g) {
        //初始化双缓存图片对象
        if (offScreenImage == null) {
            offScreenImage = createImage(600, 800);//大小和窗口大小相同即可
        }
        //创建绘画
        //获取双缓存图片对象的画笔
        Graphics gImage = offScreenImage.getGraphics();
        gImage.fillRect(0, 0, 600, 800);

        //绘制游戏的图片
        if (state == 0) {
            //游戏未开始状态
            gImage.drawImage(GameUtils.bgImgs, 0, 0, null);
            gImage.drawImage(GameUtils.explodeImgs, 270, 250, null);
            gImage.drawImage(GameUtils.planeImgs, 280, 350, null);
            gImage.drawImage(GameUtils.bossImgs, 190, 70, null);

            //获取游戏开始界面的文字
            gImage.setColor(Color.BLUE);
            gImage.setFont(new Font("仿宋", Font.BOLD, 30));
            gImage.drawString("飞机大战v1.0低配版", 180, 500);
            gImage.setColor(Color.GREEN);
            gImage.drawString("游戏说明：", 250, 550);
            gImage.drawString("鼠标左键开始游戏", 180, 600);
            gImage.drawString("按空格可以进行暂停", 180, 650);
        }
        if (state == 1) {
            //游戏中状态
            //将爆炸集合添加到所有元素集合当中
            GameUtils.gameObjList.addAll(GameUtils.explodeObjList);
            //把游戏元素加入所有元素集合当中(不再单独绘制某个游戏元素)
            for (int i = 0; i < GameUtils.gameObjList.size(); i++) {
                //把所有元素集合的对象遍历出来并且进行绘制自身
                GameUtils.gameObjList.get(i).paintSelf(gImage);
            }
            if (score > MaxScore) {
                MaxScore = score;
            }
            //绘制游戏的计分面板
            GameUtils.drawWord(gImage, "最高得分为" + MaxScore + "分", Color.GREEN, 20, 400, 100);
            GameUtils.drawWord(gImage, "当前有" + PlaneObj.skill + "个技能", Color.MAGENTA, 25, 400, 150);
            GameUtils.drawWord(gImage, "按下a键清屏子弹", Color.GREEN, 20, 400, 200);
            GameUtils.drawWord(gImage, "按下d键生成保护罩", Color.GREEN, 20, 400, 250);
            GameUtils.drawWord(gImage, "目前得" + score + "分", Color.GREEN, 30, 200, 100);
            //将要移除的元素从所有元素集合当中删除
            GameUtils.gameObjList.removeAll(GameUtils.removeList);
            count++;
            //技能1
            if (PlaneObj.skillUsing == 1) {
                skillCount++;
                //清屏子弹的维持时长
                if (skillCount > 50) {
                    PlaneObj.skillUsing = 0;
                    skillCount = 0;
                }
            }
            //技能2
            if (PlaneObj.skillUsing == 2) {
                skillCount++;
                //保护盾维持时长
                if (skillCount > 300) {
                    PlaneObj.skillUsing = 0;
                    skillCount = 0;
                }
            }

            //绘画出保护罩的图片
            if (PlaneObj.skillUsing == 2) {
                gImage.drawImage(GameUtils.safetyLineImgs, 0, 450, null);
            }
        }
        if (state == 2) {
            //游戏暂停
            gImage.drawImage(GameUtils.bgImgs, 0, 0, null);
            GameUtils.drawWord(gImage, "游戏暂停", Color.YELLOW, 50, 200, 300);
            GameUtils.drawWord(gImage, "点击空格继续", Color.YELLOW, 50, 200, 400);
        }
        if (state == 3) {
            stopMusic();
            //游戏失败
            gImage.drawImage(GameUtils.bgImgs, 0, 0, null);
            GameUtils.drawWord(gImage, "游戏失败", Color.RED, 50, 200, 300);
            GameUtils.drawWord(gImage, "鼠标点击左键重新开始挑战", Color.RED, 30, 100, 400);
            if (score > MaxScore) {
                MaxScore = score;
            }
            //绘制游戏的计分面板
            GameUtils.drawWord(gImage, "当前最高得分为" + MaxScore + "分", Color.GREEN, 30, 100, 100);
            //加1秒的延迟
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        if (state == 4) {
            stopMusic();
            //游戏胜利
            gImage.drawImage(GameUtils.bgImgs, 0, 0, null);
            GameUtils.drawWord(gImage, "游戏通关", Color.GREEN, 50, 200, 300);
            GameUtils.drawWord(gImage, "点击鼠标左键可以重新挑战", Color.GREEN, 20, 200, 400);
            //加1秒的延迟
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //将双缓存图片绘制在游戏窗口
        g.drawImage(offScreenImage, 0, 0, null);
        //观察一下所有元素集合的长度（判断一下游戏的运行过程是否清除了所有集合的元素）
        //越来越大说明清除不彻底
        //System.out.println(GameUtils.removeList.size());
        //System.out.println(state);
    }

    //批量创建物体的方法
    void createObj() {
        //通过记录图片绘制的次数来控制子弹生成的次数（速度）
        if (count % 8 == 0) {
            //创建一级子弹
            if (planeObj.times == 0) {
                musicShoot1.play(new File("Musics\\Myshoot1.wav"));
                //创建子弹对象并放到子弹集合当中
                GameUtils.shellObjList.add(new ShellObj(GameUtils.shellImgs, 14, 29, planeObj.getX() + 12, planeObj.getY() - 20, 5, this));
                //添加到所有元素集合中的对象是新new出来的子弹对象，并不是整个集合
                GameUtils.gameObjList.add(GameUtils.shellObjList.get(GameUtils.shellObjList.size() - 1));
            }
            //创建二级子弹
            if (planeObj.times == 1) {
                musicShoot2.play(new File("Musics\\Myshoot2.wav"));
                //创建子弹对象并放到子弹集合当中
                GameUtils.doubleShellObjList.add(new DoubleShellObj(GameUtils.doubleShellImgs, 32, 64, planeObj.getX() + 5, planeObj.getY() - 20, 8, this));
                //添加到所有元素集合中的对象是新new出来的子弹对象，并不是整个集合
                GameUtils.gameObjList.add(GameUtils.doubleShellObjList.get(GameUtils.doubleShellObjList.size() - 1));
            }
            //创建三级子弹
            if (planeObj.times == 2) {
                musicShoot3.play(new File("Musics\\Myshoot3.wav"));
                //创建子弹对象并放到子弹集合当中
                GameUtils.tripleShellObjList.add(new TripleShellObj(GameUtils.tripleShellImgs, 64, 182, planeObj.getX() - 5, planeObj.getY() - 100, 15, this));
                //添加到所有元素集合中的对象是新new出来的子弹对象，并不是整个集合
                GameUtils.gameObjList.add(GameUtils.tripleShellObjList.get(GameUtils.tripleShellObjList.size() - 1));
            }
        }

        //两种普通敌方飞机
        //控制敌方小飞机的产生速度
        if (count % 30 == 0) {
            GameUtils.enemy1ObjList.add(new Enemy1Obj(GameUtils.enemy1Imgs, 32 - 10, 24 - 20, (int) (Math.random() * 10) * 60, 0, 5, this));
            //添加到所有元素集合中的对象是新new出来的子弹对象，并不是整个集合
            GameUtils.gameObjList.add(GameUtils.enemy1ObjList.get(GameUtils.enemy1ObjList.size() - 1));
        }

        //控制敌方大飞机子弹的产生速度(控制count每个大飞机只能产生三发子弹)
        if (count % 50 == 0) {
            //控制敌方大飞机的产生速度
            if (count % 150 == 0) {
                GameUtils.enemy2ObjList.add(new Enemy2Obj(GameUtils.enemy2Imgs, 44 - 10, 67 - 20, (int) (Math.random() * 10) * 60, 0, 1, this));
                //添加到所有元素集合中的对象是新new出来的对象，并不是整个集合
                GameUtils.gameObjList.add(GameUtils.enemy2ObjList.get(GameUtils.enemy2ObjList.size() - 1));
            }
            if (GameUtils.enemy2ObjList.size() > 0) {
                //这里的x和y就是最新产生的敌方大飞机对象的位置，我们要用这个位置来产生敌方大飞机的子弹
                int x = (GameUtils.enemy2ObjList.get(GameUtils.enemy2ObjList.size() - 1)).getX();
                int y = (GameUtils.enemy2ObjList.get(GameUtils.enemy2ObjList.size() - 1)).getY();
                GameUtils.enemy2BulletList.add(new Enemy2BulletObj(GameUtils.enemy2BulletImgs, 14 - 10, 25 - 20, x + 17, y + 55, 5, this));
                GameUtils.gameObjList.add(GameUtils.enemy2BulletList.get(GameUtils.enemy2BulletList.size() - 1));
            }
        }
        //boss2的子弹产生速度
        if (count % 50 == 0) {
            //小boss2出现的时间
            if (count == 400 || count == 3100) {
                GameUtils.littleBoss2List.add(new LittleBoss2(GameUtils.littleboss2Imgs, 172 - 10, 112 - 20, 300, -150, 2, this));
                //添加到所有元素集合中的对象是新new出来的对象，并不是整个集合
                GameUtils.gameObjList.add(GameUtils.littleBoss2List.get(GameUtils.littleBoss2List.size() - 1));
            }
            //当boss2生成后才创建子弹集合
            if (GameUtils.littleBoss2List.size() > 0) {
                musicTracking.play(new File("Musics\\TrackingMissile.wav"));
                //这里的x和y就是最新产生的敌方boss2对象的位置，我们要用这个位置来产生敌方boss2的子弹
                int x = (GameUtils.littleBoss2List.get(GameUtils.littleBoss2List.size() - 1)).getX();
                int y = (GameUtils.littleBoss2List.get(GameUtils.littleBoss2List.size() - 1)).getY();
                GameUtils.littleBoss2BulletList.add(new LittleBoss2Bullet(GameUtils.littleBoss2BulletImgs, 21, 59 - 20, x + 75, y + 100, 8, this));
                GameUtils.gameObjList.add(GameUtils.littleBoss2BulletList.get(GameUtils.littleBoss2BulletList.size() - 1));
            }
        }
        //小boss1出现的时间
        if (count == 500 && !(GameUtils.gameObjList.contains(littleBoss1))) {
            GameUtils.gameObjList.add(littleBoss1);
        }

        //小boss1的子弹产生速度
        if (count % 25 == 0) {
            //当boss1生成后才创建子弹集合
            if (GameUtils.gameObjList.contains(littleBoss1)) {
                GameUtils.littleBoss1BulletList.add(new LittleBoss1Bullet(GameUtils.littleBoss1BulletImgs, 25 - 10, 26 - 20, littleBoss1.getX() + 75, littleBoss1.getY() + 100, 4, this));
                GameUtils.gameObjList.add(GameUtils.littleBoss1BulletList.get(GameUtils.littleBoss1BulletList.size() - 1));
            }
        }

        //大boss出现的时间
        if (count == 3100 && (!GameUtils.gameObjList.contains(bossObj))) {
            GameUtils.gameObjList.add(bossObj);
        }
        //大boss子弹的产生速度
        if (count % 20 == 0) {
            //当大boss出现时才创建子集合
            if (GameUtils.gameObjList.contains(bossObj)) {
                //1.敌方boss1子弹
                GameUtils.littleBoss1BulletList.add(new LittleBoss1Bullet(GameUtils.littleBoss1BulletImgs, 42 - 10, 42 - 20, bossObj.getX() + 10, bossObj.getY() + 130, 6, this));
                GameUtils.gameObjList.add(GameUtils.littleBoss1BulletList.get(GameUtils.littleBoss1BulletList.size() - 1));
                if (count % 30 == 0) {
                    musicTracking.play(new File("Musics\\TrackingMissile.wav"));
                    //2.敌方boss2子弹
                    GameUtils.littleBoss2BulletList.add(new LittleBoss2Bullet(GameUtils.littleBoss2BulletImgs, 21, 59 - 20, bossObj.getX() + 220, bossObj.getY() + 130, 10, this));
                    GameUtils.gameObjList.add(GameUtils.littleBoss2BulletList.get(GameUtils.littleBoss2BulletList.size() - 1));
                }
                //3.boss独有子弹
                GameUtils.bossBulletList.add(new BossBullet(GameUtils.bossBulletImgs, 51 - 10, 72 - 20, bossObj.getX() + 70, bossObj.getY() + 100, 9, this));
                GameUtils.gameObjList.add(GameUtils.bossBulletList.get(GameUtils.bossBulletList.size() - 1));
            }
        }
        //警示标志出现的时间(加个判断避免重复添加)
        if (count == 3000 && (!GameUtils.gameObjList.contains(warningObj))) {
            musicWarning.play(new File("Musics\\warning.wav"));
            GameUtils.gameObjList.add(warningObj);
        }
        //警示表示的消失时间
        if (count == 3050) {
            GameUtils.removeList.add(warningObj);
        }
        //技能补给品出现的时间
        if (count == 300 || count == 1000 || count == 3000 || count == 4000) {
            SkillGiftObj cleanBullet = new SkillGiftObj(300, 0);
            GameUtils.skillGiftObjList.add(cleanBullet);
            GameUtils.gameObjList.addAll(GameUtils.skillGiftObjList);
        }
    }

    //数据初始化
    void myInitData() {
        //需要把上次游戏所创建的对象都删除（否则游戏数据还在集合当中）
        GameUtils.gameObjList.removeAll(GameUtils.gameObjList);
        GameUtils.gameObjList.removeAll(GameUtils.removeList);
        GameUtils.littleBoss2List.removeAll(GameUtils.removeList);
        //背景图片对象的属性初始化(背景图从上往下移动)
        bgobj = new Bgobj(GameUtils.bgImgs, 0, -1000, 2);
        //我方飞机的对象
        planeObj = new PlaneObj(GameUtils.planeImgs, 37 - 15, 41 - 20, 290, 550, 0, this);
        //一个图片变量(初始化游戏没开始的图片)
        offScreenImage = null;
        //记录游戏图片绘制的次数
        count = 1;
        //刷新数据
        state = 0;
        score = 0;
        PlaneObj.times = 0;
        PlaneObj.skillUsing = 0;
        PlaneObj.skill = 0;
        //敌方1号小boss的对象
        littleBoss1 = new LittleBoss1(GameUtils.littleboss1Imgs, 172, 112, -200, 350, 3, this);
        //敌方2号小boss的对象
        littleBoss2 = new LittleBoss2(GameUtils.littleboss2Imgs, 172, 112, 300, -150, 2, this);
        //敌方大boss的对象
        bossObj = new BossObj(GameUtils.bossImgs, 240, 174, 180, -180, 3, this);
        //警示标志的对象
        warningObj = new WarningObj(GameUtils.warningImgs, 599, 90, 0, 350, 0, this);
        //将所有要绘制的游戏物体全部放入所有元素集合中进行绘制
        GameUtils.gameObjList.add(bgobj);
        GameUtils.gameObjList.add(planeObj);
        //播放音乐
        musicBg.start(new File("Musics\\战争进化史.wav"));
    }

    //鼠标事件（重新启动）
    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getButton() == 1 && state == 0) {
            //当游戏处于未开始的状态
            state = 1;//游戏开始状态
        }
        if (e.getButton() == 1 && state == 3 || e.getButton() == 1 && state == 4) {
            musicBg.stop();//关闭音乐
            stopMusic();
            //刷新游戏数据
            initWindow();
            myInitData();
        }
    }

    //键盘事件(暂停，或者释放技能)
    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        //System.out.println(code);     //32为空格
        //控制暂停和继续
        if (code == 32) {
            if (state == 1) {
                stopMusic();
                state = 2;
            } else if (state == 2) {
                state = 1;
            }
        }
        //控制技能的释放
        //清屏子弹
        if (code == 65 && state == 1 && PlaneObj.skill > 0) {
            GameUtils.removeList.addAll(GameUtils.littleBoss2BulletList);
            GameUtils.removeList.addAll(GameUtils.bossBulletList);
            GameUtils.removeList.addAll(GameUtils.littleBoss1BulletList);
            GameUtils.removeList.addAll(GameUtils.enemy2BulletList);
            PlaneObj.skillUsing = 1;
            PlaneObj.skill--;
        }
        //生成保护罩
        if (code == 68 && state == 1 && PlaneObj.skill > 0) {
            PlaneObj.skillUsing = 2;
            PlaneObj.skill--;
        }

    }

    //暂停音乐
    private void stopMusic() {
        if (PlaneObj.times == 1) {
            musicShoot1.stop();
        }
        if (PlaneObj.times == 2) {
            musicShoot2.stop();
        }
        if (PlaneObj.times == 3) {
            musicShoot3.stop();
        }
        if (GameUtils.littleBoss2List.contains(littleBoss2)) {
            musicTracking.stop();
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }


    @Override
    public void keyReleased(KeyEvent e) {
    }
}
